#include "copyright.h"
#include "BoundedBuffer2.h"
#include "synch.h"
#include "system.h"
BoundedBuffer2::BoundedBuffer2(int maxsize){
	buffer = (char*) AllocBoundedArray(maxsize);
	ASSERT(buffer != NULL);
	mutex = new Semaphore("BoundedBuffer2 mutex",1);
	fullbuffers = new Semaphore("BoundedBuffer2 fullbuffers",0);
	emptybuffers = new Semaphore("BoundedBuffer2 emptybuffers",maxsize);
	max = maxsize;
	head = 0;
	tail = 0;
	usage = 0;
}

BoundedBuffer2::~BoundedBuffer2(){
	delete mutex;
	delete emptybuffers;
	delete fullbuffers;
}

bool BoundedBuffer2::isFull(){
	return((head==tail)&&(usage!=0));//if usage=0 then empty
}

bool BoundedBuffer2::isEmpty(){
	return((head==tail)&&(usage==0));//if usage!=0 then full
}

void BoundedBuffer2::Deposit(void *data){
	emptybuffers->P();
	mutex->P();
	char temp =*(char *)data;
	*(buffer+tail)=temp;
	printf("CurrentThread:%s\nDeposite-buffer[%d]:%d.\n",
	currentThread->getName(),tail,temp);
	//example output:
	//CurrentThread:Write-Thread-0
	//Deposite-buffer[2]:1.
	tail=(tail+1)%max;
	usage++;
	mutex->V();
	fullbuffers->V();
}

void *BoundedBuffer2::Remove(){
	fullbuffers->P();
	mutex->P();
	void *ret;
	ret=buffer+head;
	char temp = *(char *)ret;
	printf("CurrentThread:%s\nConsumed-buffer[%d]:%d.\n",
	currentThread->getName(),head,temp);
	//example output:
	//CurrentThread:Read-Thread-1
	//Consumed-buffer[2]:2.
	head=(head+1)%max;
	usage--;
	mutex->V();
	emptybuffers->V();
	return ret;
}

void BoundedBuffer2::Read(char *data, int size){
	for(int i=0;i<size;i++){
		char *ret =(char *)Remove();
		char temp = *ret;
		data[i]=temp;
	}
}

void BoundedBuffer2::Write(char *data,int size){
	for(int i=0;i<size;i++){
		Deposit(data+i);
	}
}
